package byggeTegningGUI;

import context.*;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.image.BufferedImage;
//import java.awt.event.AdjustmentListener;
//import java.awt.event.AdjustmentEvent;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.GraphicsConfigTemplate3D;
import javax.media.j3d.Screen3D;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
//import javax.swing.JScrollBar;

import printCanvas3D.OffScreenCanvas3D;

import com.sun.j3d.utils.universe.SimpleUniverse;


// ***************************************************************************
// *** CLASS: JScenePanel
// ***************************************************************************
public class JScenePanel extends JPanel implements Context.Constants
{ //private static final boolean DEBUG=true; // Overriding Context.Constants.DEBUG

  static final long serialVersionUID=0; // TODO ?
  private static final int OFF_SCREEN_SCALE = 1;// 3;
  
//  //  minimum=0, maximum=100, value=0, extent=10
//  private JScrollBar horisontalScrollBar=new JScrollBar(JScrollBar.HORIZONTAL);
//  private JScrollBar verticalScrollBar=new JScrollBar(JScrollBar.VERTICAL);
//  
//  private AdjustmentListener adjustmentListener=new AdjustmentListener()
//  { public void adjustmentValueChanged(AdjustmentEvent e)
//    { if(DEBUG) Debug.println("JScenePanel'adjustmentValueChanged: "+e);   
//    }
//  };
  
  private SimpleUniverse universe;
  private Canvas3D onScreenCanvas3D;
  private OffScreenCanvas3D offScreenCanvas3D;

  // *************************************************************************
  // *** CONSTRUCTOR: JScenePanel
  // *************************************************************************
  public JScenePanel(BranchGroup scene)
  { JPopupMenu.setDefaultLightWeightPopupEnabled(false);
    this.addComponentListener(componentListener);
    this.setBackground(Color.white);
    setLayout(new BorderLayout());
    // Create Canvas3D and SimpleUniverse; add canvas to drawing panel
    onScreenCanvas3D = createUniverse(scene);
    add("Center",onScreenCanvas3D);    
//    add("South",horisontalScrollBar);    
//    add("East",verticalScrollBar);    
    // Create the off-screen Canvas3D object
    createOffScreenCanvas(onScreenCanvas3D);
//    horisontalScrollBar.addAdjustmentListener(adjustmentListener);
//    verticalScrollBar.addAdjustmentListener(adjustmentListener);
  }

  private Canvas3D createUniverse(BranchGroup scene)
  { GraphicsConfiguration config=SimpleUniverse.getPreferredConfiguration();
    Canvas3D canvas3D=new Canvas3D(config);
    universe=new SimpleUniverse(canvas3D);
    // This will move the ViewPlatform back a bit so the
    // objects in the scene can be viewed.
    universe.getViewingPlatform().setNominalViewingTransform();
    // Ensure at least 5 msec per frame (i.e., < 200Hz)
    universe.getViewer().getView().setMinimumFrameCycleTime(5);
    // Attach the scene to the virtual universe
    universe.addBranchGraph(scene);
    return(canvas3D);
  }


  private OffScreenCanvas3D createOffScreenCanvas(Canvas3D onScreenCanvas3D)
  { // Create the off-screen Canvas3D object
    // request an offscreen Canvas3D with a single buffer configuration
    GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
    template.setDoubleBuffer(GraphicsConfigTemplate3D.UNNECESSARY);
    GraphicsConfiguration gc
     = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getBestConfiguration(template);

    offScreenCanvas3D = new OffScreenCanvas3D(gc, true);
    // Set the off-screen size based on a scale factor times the
    // on-screen size
    Screen3D sOn = onScreenCanvas3D.getScreen3D();
    Screen3D sOff = offScreenCanvas3D.getScreen3D();
    Dimension dim = sOn.getSize();
    dim.width *= OFF_SCREEN_SCALE;
    dim.height *= OFF_SCREEN_SCALE;
    sOff.setSize(dim);
    sOff.setPhysicalScreenWidth(sOn.getPhysicalScreenWidth() * OFF_SCREEN_SCALE);
    sOff.setPhysicalScreenHeight(sOn.getPhysicalScreenHeight() * OFF_SCREEN_SCALE);

    // attach the offscreen canvas to the view
    universe.getViewer().getView().addCanvas3D(offScreenCanvas3D);        

    return(offScreenCanvas3D);
        
  }

  public BufferedImage snapShot()
  {
    //if(DEBUG) Debug.println("JScenePanel.snapShot");
    Point loc = onScreenCanvas3D.getLocationOnScreen();
    offScreenCanvas3D.setOffScreenLocation(loc);
    Dimension dim = onScreenCanvas3D.getSize();
    dim.width *= OFF_SCREEN_SCALE;
    dim.height *= OFF_SCREEN_SCALE;
    BufferedImage bImage=offScreenCanvas3D.doRender(dim.width, dim.height);
    return(bImage);
  }

  // ***************************************************************************
  // *** ComponentListener: Methods
  // ***************************************************************************
  private ComponentListener componentListener=new ComponentListener()
  {
    //** Invoked when the component's size changes. **/
    public void componentResized(ComponentEvent e) { }

    //** Invoked when the component's position changes. **/
    public void componentMoved(ComponentEvent e) {}

    //** Invoked when the component has been made visible. **/
    public void componentShown(ComponentEvent e) {}

    //** Invoked when the component has been made invisible. **/
    public void componentHidden(ComponentEvent e) {}

  };

}